package org.jl.main;

import org.jl.main.model.User;
import org.jl.main.util.UtilForCollection;

import java.util.*;
import java.util.stream.Collectors;

/**
 * java集合转换
 */
public class Main02_2_Collection {

    //常量名大写
    public static final List<User> USERS1 = new ArrayList<>();
    public static final List<User> USERS2 = new ArrayList<>();

    static {
        User u1 = User.builder().userCode("0001").userName("张三").userAge(18).build();
        User u2 = User.builder().userCode("0002").userName("李四").userAge(17).build();
        User u3 = User.builder().userCode("0003").userName("王五").userAge(19).build();
        UtilForCollection.of(USERS1, u1, u2, u3);
        UtilForCollection.of(USERS2, u1, u2, u3, u1);
    }

    /*
    stream的用法
    运营结果：
    USERS1 sort:[User(id=null, userCode=0002, userName=李四, userAge=17), User(id=null, userCode=0001, userName=张三, userAge=18), User(id=null, userCode=0003, userName=王五, userAge=19)]
    users1 sorted:[User(id=null, userCode=0002, userName=李四, userAge=17), User(id=null, userCode=0001, userName=张三, userAge=18), User(id=null, userCode=0003, userName=王五, userAge=19)]

    users1 filter:[User(id=null, userCode=0002, userName=李四, userAge=17)]

    users2 groupingBy:{17=[User(id=null, userCode=0002, userName=李四, userAge=17)], 18=[User(id=null, userCode=0001, userName=张三, userAge=18), User(id=null, userCode=0001, userName=张三, userAge=18)], 19=[User(id=null, userCode=0003, userName=王五, userAge=19)]}
     */
    public static void main1(String[] args) {
        //排序，改变列表顺序
        USERS1.sort(Comparator.comparingInt(User::getUserAge));
        System.out.println("USERS1 sort:" + USERS1);
        //流排序，不改变源列表顺序
        List<User> users1 = USERS1.stream().sorted(Comparator.comparingInt(User::getUserAge)).toList();
        System.out.println("users1 sorted:" + users1 + "\n");

        //过滤
        users1 = USERS1.stream().filter(u -> (u.getUserAge() < 18)).toList();
        System.out.println("users1 filter:" + users1 + "\n");

        //分组
        Map<Integer, List<User>> users2 = USERS2.stream().collect(Collectors.groupingBy(User::getUserAge));
        System.out.println("users2 groupingBy:" + users2 + "\n");

        //合并
        List<Integer> numbers = List.of(1, 2, 3, 4, 5);
        int sum = numbers.stream().reduce(0, Integer::sum);
        System.out.println("The sum is " + sum);
        int max = numbers.stream().reduce(0, Integer::max);
        System.out.println("The max is " + max + "\n");
    }

    /*
    集合转换-列表
    运营结果：
    USERS2 to List<String>:[0001, 0002, 0003, 0001]
    USERS2 distinct to List<String>:[0001, 0002, 0003]

    USERS2 to Set<String> ex1:[0002, 0003, 0001]
    USERS2 to Set<String> ex2:[0002, 0003, 0001]

    USERS1 to Map<String, String>:{0002=李四, 0003=王五, 0001=张三}
    USERS1 to Map<String, User>:{0002=User(id=null, userCode=0002, userName=李四, userAge=17), 0003=User(id=null, userCode=0003, userName=王五, userAge=19), 0001=User(id=null, userCode=0001, userName=张三, userAge=18)}
    USERS2 to Map<String, User>:{0002=User(id=null, userCode=0002, userName=李四, userAge=17), 0003=User(id=null, userCode=0003, userName=王五, userAge=19), 0001=User(id=null, userCode=0001, userName=张三, userAge=18)}

    users1 to String:0001,0002,0003,0001
    users1 to SQL String:'0001','0002','0003','0001'
    s1 to List<String>:[0001, 0002, 0003, 0001]

    users1 to Array:[0001, 0002, 0003, 0001]
    objs to List<String>:[0001, 0002, 0003, 0001]
     */
    public static void main2(String[] args) {
        //对象列表->属性列表
        List<String> users1 = USERS2.stream().map(User::getUserCode).toList();
        System.out.println("USERS2 to List<String>:" + users1);
        users1 = USERS2.stream().map(User::getUserCode).distinct().collect(Collectors.toList());
        System.out.println("USERS2 distinct to List<String>:" + users1 + "\n");

        //list -> set
        Set<String> users2 = USERS2.stream().map(User::getUserCode).collect(Collectors.toSet());
        System.out.println("USERS2 to Set<String> ex1:" + users2);
        System.out.println("USERS2 to Set<String> ex2:" + new HashSet<>(users1) + "\n");

        //list->map
        //注：Collectors.toMap的value不允许为空
        //注：Collectors.toMap默认不支持key重复，需要通过第三个参数设置覆盖规则
        Map<String, String> users3 = USERS1.stream().collect(Collectors.toMap(User::getUserCode, User::getUserName));
        System.out.println("USERS1 to Map<String, String>:" + users3);
        Map<String, User> users4 = USERS1.stream().collect(Collectors.toMap(User::getUserCode, (u) -> u));
        System.out.println("USERS1 to Map<String, User>:" + users4);
        users4 = USERS2.stream().collect(Collectors.toMap(User::getUserCode, (u) -> u, (v1, v2) -> v2));
        System.out.println("USERS2 to Map<String, User>:" + users4 + "\n");

        //list->string->list
        //属性列表->逗号间隔字符串
        String s1 = String.join(",", users1);
        System.out.println("users1 to String:" + s1);
        //属性列表->sql语句逗号间隔字符串
        String s2 = "'" + String.join("','", users1) + "'";
        System.out.println("users1 to SQL String:" + s2);
        //逗号间隔字符串->属性列表
        users1 = Arrays.asList(s1.split(","));
        System.out.println("s1 to List<String>:" + users1);
        List<Integer> users5 = users1.stream().map(Integer::parseInt).toList();
        System.out.println("List<String> to List<Integer>:" + users5 + "\n");

        //list->array->list，参数用于指定类型
        String[] objs = users1.toArray(new String[0]);
        System.out.println("users1 to Array:" + Arrays.toString(objs));
        users1 = Arrays.stream(objs).toList();
        System.out.println("objs to List<String>:" + users1 + "\n");
    }

    /*
    集合转换-集
    运营结果：
    set1 to List<String>:[c, b, a]

    set1 to Array:[c, b, a]
     */
    public static void main3(String[] args) {
        //set->list
        Set<String> set1 = Set.of("a", "b", "c");
        List<String> list1 = set1.stream().toList();
        System.out.println("set1 to List<String>:" + list1 + "\n");

        //set->array
        String[] objs = set1.toArray(new String[0]);
        System.out.println("set1 to Array:" + Arrays.toString(objs) + "\n");
    }

    /*
    集合转换-映射
    运营结果：
    map4 keys to Set<String>[a, b]
    map4 values to Set<String>[1, 2]
     */
    public static void main4(String[] args) {
        //map->set
        Map<String, String> map4 = new HashMap<>();
        UtilForCollection.of(map4, "a", "1", "b", "2");
        //键集
        System.out.println("map4 keys to Set<String>" + map4.keySet());
        //列集
        System.out.println("map4 values to Set<String>" + new HashSet<>(map4.values()) + "\n");
    }

}
